React Fiber
Reconsiliation
~v15まで
Stackというアルゴリズムが使われていた
基本的に仮想DOMのツリーを上から再帰的に比較していくというもの
途中で停止することもできない
更新処理の間アプリケーションがフリーズする
DOM treeがでかくなると大変。DeveloperがshouldComponentUpdateで制御しないといけなくなったりする
v16~
再帰的な処理をやめてReactElementごとの更新処理をLinked Listにして、一つ一つの更新処理を独立したものとして扱えるようにしたもの それぞれのジョブが独立しているので途中停止できる
個々のジョブに優先度を付けられる
FiberはReactElementとほぼ一対一に対応し、ほかのFiberと親子や兄弟の関係を構築する
CのStructにできるような互換性がある。将来的にWASMが来るかも
Reactを使ったターミナルアプリも作りやすくなっている
DOMの更新
DOMの更新などの副作用はReconciliationの最後、Commit Phaseで行われる
Fiberという単位で処理を分割することにより、Fiberのスケジューリングが可能に
JavaScriptは基本的にシングルスレッドなので優先度付きの擬似的なスケジューリング
優先度の低いFiber: requestIdleCallback()を使って、ブラウザの処理がひまになった時に実行される
優先度の高いFiber: requestAnimationFrame() を使い、できるだけ早いタイミングで実行される
DOMの更新処理にも、遅延が許されるものとそうでないものがある
<input type="text">のvalueは優先度高く更新しないと体験が悪い
入力を受けて副次的に表示されるようなところは優先度が低くてもよい
two phases
Render
副作用を抽出する役割
DOMに同期しないので副作用の抽出は非同期でできる
中断可能
xxxWillxxx 系のライフサイクルメソッドが deprecated になったのは一対一である保証がなくなったため
副作用(Side Effect)とは
Commit phase処理されるイベント
イベントは2進数で定義されている
Update QueueというLinked Listに入れられる
Commit
副作用をhost(DOM)に反映させる
ここは必ず同期しなければならない
componentDidxxx
https://user-images.githubusercontent.com/103419/40556102-4b539a02-6043-11e8-9d23-5e74e9b80bf6.png
メリット
レスポンスの向上
Fiberは単純な速度の向上ではなくレスポンスの向上を目指したアップデート
スピードではなくレスポンスの向上を目指している
ベンチマーク結果が劇的に向上するようなことはない
ダブルバッファリング
次に表示するUIをバックグラウンドで描画しておくことで、ちらつきや遅延なく、素早くUIを切り替えられるようにする技術
current fiber: 実際のDOMに反映されている。ユーザーが見ている
work in progress fiber: 次に表示する。バックグラウンドで描画される
HTML要素のhidden属性を使用して、オフスクリーンでDOMをレンダリングしておく
Stackではできなかった
バックグラウンドで描画する処理もメインスレッド上で同期的に行われるためUIを阻害する
React Fiberでは、オフスクリーン・プライオリティという低い優先度が使用され、ブラウザがアイドル状態の時を狙って非同期に実行される。UI処理を阻害しない